import sys
import os
import subprocess
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                            QHBoxLayout, QLabel, QPushButton, QListWidget,
                            QLineEdit, QMessageBox, QProgressBar, QComboBox,
                            QGroupBox, QGridLayout)
from PyQt5.QtCore import QProcess, Qt, QSettings, QProcessEnvironment

class NodeVersionManager(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Node.js 版本管理器")
        self.setGeometry(100, 100, 800, 600)
        self.settings = QSettings("NodeJS Manager", "Config")
        
        # 主窗口部件
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        
        # 布局
        self.main_layout = QVBoxLayout()
        self.central_widget.setLayout(self.main_layout)
        
        # 当前版本显示
        self.current_version_label = QLabel("当前Node.js版本: 检测中...")
        self.main_layout.addWidget(self.current_version_label)
        
        # 镜像配置部分
        self.create_mirror_section()
        
        # 常用版本快速安装部分
        self.create_quick_install_section()
        
        # 版本列表
        version_list_group = QGroupBox("已安装版本")
        version_list_layout = QVBoxLayout()
        self.version_list = QListWidget()
        version_list_layout.addWidget(self.version_list)
        version_list_group.setLayout(version_list_layout)
        self.main_layout.addWidget(version_list_group)
        
        # 控制按钮
        self.control_layout = QHBoxLayout()
        
        self.install_button = QPushButton("安装版本")
        self.install_button.clicked.connect(self.install_version)
        self.install_button.setStyleSheet("background-color: #4CAF50; color: white;")
        self.control_layout.addWidget(self.install_button)
        
        self.use_button = QPushButton("使用此版本")
        self.use_button.clicked.connect(self.use_version)
        self.use_button.setStyleSheet("background-color: #2196F3; color: white;")
        self.control_layout.addWidget(self.use_button)
        
        self.remove_button = QPushButton("移除版本")
        self.remove_button.clicked.connect(self.remove_version)
        self.remove_button.setStyleSheet("background-color: #f44336; color: white;")
        self.control_layout.addWidget(self.remove_button)
        
        self.main_layout.addLayout(self.control_layout)
        
        # 版本输入
        self.version_input_layout = QGridLayout()
        
        self.version_label = QLabel("输入版本号:")
        self.version_input_layout.addWidget(self.version_label, 0, 0)
        
        self.version_input = QLineEdit()
        self.version_input.setPlaceholderText("输入要安装的Node.js版本 (如: 16.13.0)")
        self.version_input_layout.addWidget(self.version_input, 0, 1)
        
        self.install_custom_button = QPushButton("安装")
        self.install_custom_button.clicked.connect(self.install_version)
        self.install_custom_button.setStyleSheet("background-color: #4CAF50; color: white;")
        self.version_input_layout.addWidget(self.install_custom_button, 0, 2)
        
        self.main_layout.addLayout(self.version_input_layout)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        self.main_layout.addWidget(self.progress_bar)
        
        # 初始化
        self.check_current_version()
        self.load_installed_versions()
        self.load_settings()
    
    def create_mirror_section(self):
        """创建镜像配置区域"""
        mirror_group = QGroupBox("镜像配置")
        mirror_layout = QGridLayout()
        
        # 镜像选择
        mirror_label = QLabel("选择镜像源:")
        mirror_layout.addWidget(mirror_label, 0, 0)
        
        self.mirror_combo = QComboBox()
        self.mirror_combo.addItems([
            "官方镜像 (nodejs.org)",
            "淘宝镜像 (npmmirror.com)",
            "华为云镜像 (mirrors.huaweicloud.com)",
            "腾讯云镜像 (mirrors.cloud.tencent.com)",
            "自定义镜像"
        ])
        self.mirror_combo.currentIndexChanged.connect(self.save_settings)
        mirror_layout.addWidget(self.mirror_combo, 0, 1, 1, 2)
        
        # 自定义镜像输入
        custom_mirror_label = QLabel("自定义镜像URL:")
        mirror_layout.addWidget(custom_mirror_label, 1, 0)
        
        self.custom_mirror_input = QLineEdit()
        self.custom_mirror_input.setPlaceholderText("https://example.com/node/")
        self.custom_mirror_input.textChanged.connect(self.save_settings)
        mirror_layout.addWidget(self.custom_mirror_input, 1, 1, 1, 2)
        
        # 应用镜像按钮
        self.apply_mirror_button = QPushButton("应用镜像设置")
        self.apply_mirror_button.clicked.connect(self.apply_mirror_settings)
        self.apply_mirror_button.setStyleSheet("background-color: #FF9800; color: white;")
        mirror_layout.addWidget(self.apply_mirror_button, 2, 0, 1, 3)
        
        mirror_group.setLayout(mirror_layout)
        self.main_layout.addWidget(mirror_group)
    
    def create_quick_install_section(self):
        """创建常用版本快速安装区域"""
        quick_install_group = QGroupBox("常用版本快速安装")
        quick_layout = QGridLayout()
        
        # LTS版本
        lts_label = QLabel("LTS版本:")
        quick_layout.addWidget(lts_label, 0, 0)
        
        self.lts_combo = QComboBox()
        self.lts_combo.addItems(["18.17.1 (推荐)", "20.6.1", "16.20.2"])
        quick_layout.addWidget(self.lts_combo, 0, 1)
        
        self.install_lts_button = QPushButton("安装")
        self.install_lts_button.clicked.connect(lambda: self.install_quick_version("lts"))
        self.install_lts_button.setStyleSheet("background-color: #4CAF50; color: white;")
        quick_layout.addWidget(self.install_lts_button, 0, 2)
        
        # 最新版本
        latest_label = QLabel("最新版本:")
        quick_layout.addWidget(latest_label, 1, 0)
        
        self.latest_combo = QComboBox()
        self.latest_combo.addItems(["21.0.0-nightly", "20.8.0", "19.9.0"])
        quick_layout.addWidget(self.latest_combo, 1, 1)
        
        self.install_latest_button = QPushButton("安装")
        self.install_latest_button.clicked.connect(lambda: self.install_quick_version("latest"))
        self.install_latest_button.setStyleSheet("background-color: #2196F3; color: white;")
        quick_layout.addWidget(self.install_latest_button, 1, 2)
        
        # 历史版本
        historical_label = QLabel("历史版本:")
        quick_layout.addWidget(historical_label, 2, 0)
        
        self.historical_combo = QComboBox()
        self.historical_combo.addItems(["14.21.3", "12.22.12", "10.24.1"])
        quick_layout.addWidget(self.historical_combo, 2, 1)
        
        self.install_historical_button = QPushButton("安装")
        self.install_historical_button.clicked.connect(lambda: self.install_quick_version("historical"))
        self.install_historical_button.setStyleSheet("background-color: #9C27B0; color: white;")
        quick_layout.addWidget(self.install_historical_button, 2, 2)
        
        quick_install_group.setLayout(quick_layout)
        self.main_layout.addWidget(quick_install_group)
    
    def get_mirror_url(self):
        """获取当前选择的镜像URL"""
        mirror_index = self.mirror_combo.currentIndex()
        mirror_text = self.mirror_combo.currentText()
        
        if mirror_index == 0:  # 官方镜像
            return "https://nodejs.org/dist/"
        elif mirror_index == 1:  # 淘宝镜像
            return "https://npmmirror.com/mirrors/node/"
        elif mirror_index == 2:  # 华为云镜像
            return "https://mirrors.huaweicloud.com/nodejs/"
        elif mirror_index == 3:  # 腾讯云镜像
            return "https://mirrors.cloud.tencent.com/nodejs-release/"
        else:  # 自定义镜像
            custom_url = self.custom_mirror_input.text().strip()
            if custom_url:
                return custom_url
            return "https://nodejs.org/dist/"
    
    def apply_mirror_settings(self):
        """应用镜像设置"""
        mirror_url = self.get_mirror_url()
        self.save_settings()
        
        # 在Windows上设置环境变量
        if os.name == 'nt':
            os.environ['NVM_NODEJS_ORG_MIRROR'] = mirror_url
            QMessageBox.information(self, "成功", f"已设置镜像源为:\n{mirror_url}\n\n此设置仅对当前会话有效！")
        else:
            # 在Unix系统上需要修改.bashrc或.zshrc等
            QMessageBox.information(self, "提示", 
                f"请将以下内容添加到您的Shell配置文件中:\n\nexport NVM_NODEJS_ORG_MIRROR={mirror_url}\n\n"
                "然后运行: source ~/.bashrc (或您的配置文件)")
    
    def install_quick_version(self, version_type):
        """安装常用版本"""
        if version_type == "lts":
            version = self.lts_combo.currentText().split()[0]
        elif version_type == "latest":
            version = self.latest_combo.currentText().split()[0]
        else:  # historical
            version = self.historical_combo.currentText().split()[0]
        
        # 设置输入框显示
        self.version_input.setText(version)
        
        # 调用安装方法
        self.install_version()
    
    def save_settings(self):
        """保存设置到注册表"""
        self.settings.setValue("mirror_index", self.mirror_combo.currentIndex())
        self.settings.setValue("custom_mirror", self.custom_mirror_input.text())
    
    def load_settings(self):
        """从注册表加载设置"""
        mirror_index = self.settings.value("mirror_index", 1, type=int)  # 默认使用淘宝镜像
        self.mirror_combo.setCurrentIndex(mirror_index)
        
        custom_mirror = self.settings.value("custom_mirror", "")
        self.custom_mirror_input.setText(custom_mirror)
    
    def check_current_version(self):
        try:
            result = subprocess.run(['node', '--version'], capture_output=True, text=True)
            if result.returncode == 0:
                self.current_version_label.setText(f"当前Node.js版本: {result.stdout.strip()}")
            else:
                self.current_version_label.setText("当前Node.js版本: 未安装")
        except FileNotFoundError:
            self.current_version_label.setText("当前Node.js版本: 未安装")
    
    def load_installed_versions(self):
        self.version_list.clear()
        try:
            result = subprocess.run(['nvm', 'ls'], capture_output=True, text=True)
            if result.returncode == 0:
                versions = result.stdout.split('\n')
                for version in versions:
                    if version.strip() and '->' not in version:  # 过滤掉当前使用箭头
                        clean_version = version.strip().replace('*', '').replace('->', '').strip()
                        if clean_version:
                            self.version_list.addItem(clean_version)
        except FileNotFoundError:
            QMessageBox.warning(self, "警告", "未找到nvm (Node Version Manager)，请先安装nvm")
    
    def install_version(self):
        version = self.version_input.text().strip()
        if not version:
            QMessageBox.warning(self, "警告", "请输入要安装的Node.js版本")
            return
            
        self.progress_bar.setVisible(True)
        self.progress_bar.setRange(0, 0)  # 不确定进度
        
        # 获取镜像URL
        mirror_url = self.get_mirror_url()
        
        # 设置环境变量
        env = QProcessEnvironment.systemEnvironment()
        env.insert("NVM_NODEJS_ORG_MIRROR", mirror_url)
        
        process = QProcess(self)
        process.setProcessEnvironment(env)
        process.start('nvm', ['install', version])
        process.finished.connect(lambda: self.on_install_finished(version))
        process.errorOccurred.connect(self.on_process_error)
    
    def on_install_finished(self, version):
        self.progress_bar.setVisible(False)
        self.load_installed_versions()
        QMessageBox.information(self, "完成", f"Node.js {version} 安装完成")
    
    def use_version(self):
        selected_item = self.version_list.currentItem()
        if not selected_item:
            QMessageBox.warning(self, "警告", "请选择一个版本")
            return
        
        version = selected_item.text().split()[0]  # 提取版本号
        process = QProcess(self)
        process.start('nvm', ['use', version])
        process.finished.connect(self.on_use_finished)
        process.errorOccurred.connect(self.on_process_error)
    
    def on_use_finished(self):
        self.check_current_version()
        QMessageBox.information(self, "完成", "版本切换完成")
    
    def remove_version(self):
        selected_item = self.version_list.currentItem()
        if not selected_item:
            QMessageBox.warning(self, "警告", "请选择一个版本")
            return
        
        version = selected_item.text().split()[0]  # 提取版本号
        reply = QMessageBox.question(self, "确认", f"确定要移除Node.js {version}吗?", 
                                    QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            process = QProcess(self)
            process.start('nvm', ['uninstall', version])
            process.finished.connect(self.on_remove_finished)
            process.errorOccurred.connect(self.on_process_error)
    
    def on_remove_finished(self):
        self.load_installed_versions()
        QMessageBox.information(self, "完成", "版本移除完成")
    
    def on_process_error(self, error):
        self.progress_bar.setVisible(False)
        QMessageBox.critical(self, "错误", f"操作失败: {error}")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    # 设置样式
    app.setStyle("Fusion")
    app.setStyleSheet("""
        QGroupBox {
            font-weight: bold;
            border: 1px solid #cccccc;
            border-radius: 5px;
            margin-top: 1ex;
            padding-top: 10px;
        }
        QGroupBox::title {
            subcontrol-origin: margin;
            subcontrol-position: top center;
            padding: 0 3px;
        }
        QLabel {
            font-size: 14px;
        }
        QPushButton {
            padding: 5px 10px;
            border-radius: 3px;
            font-weight: bold;
        }
    """)
    
    manager = NodeVersionManager()
    manager.show()
    sys.exit(app.exec_())
